import {
  AliasOptions, BuildOptions, ConfigEnv,
  CSSOptions, loadEnv, PluginOption,
  ServerOptions, UserConfig
} from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import viteCompression from 'vite-plugin-compression';
import legacy from '@vitejs/plugin-legacy';
import vueJsx from "@vitejs/plugin-vue-jsx";
import AutoImport from 'unplugin-auto-import/vite' //注意后面有个/vite
import Components from 'unplugin-vue-components/vite' //注意后面有个/vite
import proxys from './config/vite/proxy'; //配置代理的外部文件
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import'
import { viteCommonjs, esbuildCommonjs } from '@originjs/vite-plugin-commonjs';


export default (({ mode }: ConfigEnv): UserConfig => {
  // 获取 .env 环境配置文件
  const env: Record<string, string> = loadEnv(mode, process.cwd());
  /**
   * 服务配置
   */
  const server: ServerOptions = {
    host: '127.0.0.1',
    port: Number(env.VITE_APP_PORT), //服务端口号
    open: false, // 类型： boolean | string在服务器启动时自动在浏览器中打开应用程序；
    cors: true, //类型： boolean | CorsOptions 为开发服务器配置 CORS。默认启用并允许任何源（跨域）
    hmr: true,
    proxy: proxys //配置代理
  }
  /**
   * 打包配置
   */
  const build: BuildOptions = {
    cssCodeSplit: true, // 如果设置为false，整个项目中的所有 CSS 将被提取到一个 CSS 文件中
    sourcemap: false, // 构建后是否生成 source map 文件。如果为 true，将会创建一个独立的 source map 文件
    target: 'modules', // 设置最终构建的浏览器兼容目标。默认值是一个 Vite 特有的值——'modules'  还可设置为 'es2015' 'es2016'等
    chunkSizeWarningLimit: 500, //打包文件大小警告的限制 kbs单位 https://cn.vitejs.dev/config/#build-chunksizewarninglimit
    assetsInlineLimit: 4096, // 单位字节（1024等于1kb） 小于此阈值的导入或引用资源将内联为 base64 编码，以避免额外的 http 请求。设置为 0 可以完全禁用此项。
    minify: 'terser', // 'terser' 相对较慢（需要单独引入），但大多数情况下构建后的文件体积更小。'esbuild' 最小化混淆更快但构建后的文件相对更大。
    terserOptions: {
      compress: {
        drop_console: JSON.parse(env.VITE_DROP_CONSOLE), // 生产环境去除console
        drop_debugger: JSON.parse(env.VITE_DROP_CONSOLE), // 生产环境去除debugger
      },
    },
    rollupOptions: {
      output: {
        //静态资源分类打包
        chunkFileNames: 'static/js/[name]-[hash].js',
        entryFileNames: 'static/js/[name]-[hash].js',
        assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
        // 超大静态资源拆分
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return id.toString().split('node_modules/')[1].split('/')[0].toString();
          }
        },
      }
    },
    outDir: 'dist', //指定输出路径
    assetsDir: 'static' // 指定生成静态资源的存放路径
  }
  /**
   * 别名
   */
  const alias: AliasOptions = {
    "~": resolve(__dirname, "./"),
    "@": resolve(__dirname, "src"),
    "@components": resolve(__dirname, "src/components"),
    "@assets": resolve(__dirname, "src/assets"),
    "@css": resolve(__dirname, "src/assets/css"),
    "@images": resolve(__dirname, "src/assets/images"),
    "@js": resolve(__dirname, "src/assets/js"),
    "@router": resolve(__dirname, "src/router"),
  }
  /**
   * 插件
   */
  const plugins: PluginOption[] = [
    vue(),
    // vueJsx 支持
    vueJsx(),
    // 兼容ie11
    legacy({
      targets: ['defaults', 'not IE 11'],
      additionalLegacyPolyfills: ['regenerator-runtime/runtime']
    }),
    //自动导入依赖
    AutoImport({
      imports: ['vue', 'vue-router', 'pinia'],
      // 可以选择auto-import.d.ts生成的位置，使用ts建议设置为'src/auto-import.d.ts'
      dts: './config/plugins/auto-import.d.ts',
      resolvers: [AntDesignVueResolver({
        // 引入ant-design-vue/icons 图标库 ，需要下载 npm install --save @ant-design/icons-vue
        resolveIcons: true,
        // 引入style样式
        importStyle: 'less'
      })]
    }),
    // 组件自动注册
    Components({
      dirs: ['src/components'],
      resolvers: [
        // 按需引入ant-design-vue
        AntDesignVueResolver({
          // 引入ant-design-vue/icons 图标库 ，需要下载 npm install --save @ant-design/icons-vue
          resolveIcons: true,
          // 引入style样式
          importStyle: 'less'
        })
      ],
      // 按需加载
      extensions: ['vue', 'tsx'],
      // 配置文件生成位置
      dts: './config/plugins/components.d.ts'
    }),
    //gzip 压缩
    viteCompression({
      verbose: true,  // 记录压缩比
      disable: (!(JSON.parse(env.VITE_COMPRESSION_DISABLE))),  //是否开启压缩 false 为默认值为开启,true为关闭
      deleteOriginFile: true, //压缩后删除源文件
      threshold: 10240, //使用压缩前的最小文件大小。单位b
      algorithm: 'gzip', //压缩算法,可选 [ 'gzip' , 'brotliCompress' ,'deflate' , 'deflateRaw']
      ext: '.gz', // 后缀
    }),
    // 插件样式引入
    createStyleImportPlugin({
      resolves: [AndDesignVueResolve()]
    }),
    viteCommonjs() //混用Commonjs

  ]
  /**
   * 使用路径别名时想要省略的后缀名，官方不建议将.vue文件省略后缀
   */
  const extensions: string[] = [".js", ".ts"]

  /**
   * CSS选项预加载器
   */
  const css: CSSOptions = {
    modules: {
      localsConvention: 'camelCase', // 默认只支持驼峰，修改为同时支持横线和驼峰
    },
    //指定传递给 CSS 预处理器的选项
    preprocessorOptions: {
      scss: {
        charset: true,
        // 导入全局scss文件
        additionalData: `@import "@/assets/scss/var.scss";`,
        javascriptEnabled: true
      },
      less: {
        charset: true,
        javascriptEnabled: true
      },
    },
  }
  return {
    base: String(env.VITE_BASE_URL),
    plugins: plugins,
    server: server,
    build: build,
    resolve: {
      alias: alias,
      extensions: extensions
    },
    css: css,
    optimizeDeps: {
      esbuildOptions: {
        plugins: [
          esbuildCommonjs(['ant-design-vue'])
        ]
      },
      include: [
        'vue',
        'axios',
        'pinia',
        'vue-router'
      ],
    },
    envPrefix: 'VITE_' // 默认 VITE_ 以 envPrefix 开头的环境变量会通过 import.meta.env 暴露在你的客户端源码中。
  }
})



